/********test wrapper**********
#include "wrapper/wrapper.h"

#include <stdio.h>

int main(int argc, char* argv[])
{
	void * client = rtsp_initClient("test.h264");
	//client->start();
	int cnt = 1000;

	rtsp_setMaxDelay(client, 2000000);
	uint8_t buf[2000000];
	int len;
	int64_t pts;

	FILE* fout = fopen("testmain.h264", "w");

	while(1)
	{
		rtsp_demux(client);
		usleep(1000);

		cnt--;
		if(cnt < 0)
		{
			break;
		}

		//sct_LOG("ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:%d, %9lld", cnt, client->realTimeDelay());
		if(rtsp_realTimeDelay(client) > 1000000)
		{
			while(1)
			{
				len = rtsp_getVideoData(client, &pts, buf, 2000000);
				if(len<0) break;

				fwrite((char*)buf, len, 1, fout);
			}
		}
	}

	rtsp_destroyClient(client);

	return 0;
}
*/

#include "sct/rtspclient/rtspclientinterface.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>

#include "sct/core/common.h"

static sct::CRTSPClientInterface* c = NULL;

static void* recv_thread(void* arg)
{
    while(1)
    {
        usleep(1000);

       // KEEPALIVE_CHECK();

        double t1 = sct::currentTime();
        c->demux();
        double t2 = sct::currentTime();
        t2 -= t1;
        if(t2 > 0.1)
        {
            printf(">>>>>>>>>>>>>1>>>>>>>>>>>>>>>>>>>>>>>>>>>>%f deta:%f", t1, t2);
        }

    }


    return NULL;
}



int main(int argc, char* argv[])
{
	printf("test rtspclientinterface 2\n");

	c = sct::CRTSPClientInterface::create("rtspclient");
//	c->setH264SavePath("test.h264");
	c->setMaxDelay(2000000);

	int cnt = 1000;
	uint8_t buf[2000000];
	int len;
	int64_t pts;
	FILE* fout = fopen("testmain.h264", "w");

	int nFrame = 0;

	pthread_t thd;
	pthread_create(&thd, NULL, recv_thread, NULL);

	while(1)
	{
		//c->demux();

		usleep(1000);
		cnt--;
		if(cnt < 0)
		{
			//break;
		}

		//printf("ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:%d, %9lld\n", cnt, c->realTimeDelay());
		//if(c->realTimeDelay() > 1000000)
		{
			while(1)
			{
				uint32_t dropFramePre = 0;
				len = c->video_getData(&pts, buf, 2000000, &dropFramePre);
				if(len<0) break;

				nFrame++;
				printf("Get frame.....................:%d\n", nFrame);

				if(dropFramePre)
				{
					//printf("Drop some before this Frame:%d\n", len);
					printf("Drop some before this Frame\n");
				}


				//fwrite((char*)buf, len, 1, fout);
			}
		}
	}

	delete c;

	return 0;
}


/*

track for drop detected

从stream获取数据是通过：
MediaSubsession::readSource()->getNextFrame()=>当有数据时会调用afterGettingFunc函数

typedef void (afterGettingFunc)(void* clientData, unsigned frameSize,
				  unsigned numTruncatedBytes,
				  struct timeval presentationTime,
				  unsigned durationInMicroseconds);


MediaSubsession::rtpSource()和MediaSubsession::readSource()是不同的
rtpSource()=>fRTPSource
readSource()=>fReadSource
MediaSubsession::initiate()=>MediaSubsession::createSourceObjects()=>
fRTPSource = fReadSource = H264VideoRTPSource::createNew()

也就是说从stream中获取的数据从
H264VideoRTPSource::getNextFrame() {fAfterGettingFunc = afterGettingFunc} =>
MultiFrameRTPSource::doGetNextFrame() {如果还没有开始读网络数据，则开始读}=>
MultiFrameRTPSource::doGetNextFrame1() {在排序缓冲中得到一个包； 执行rfc3984; }=>
ReorderingPacketBuffer::getNextCompletedPacket() 能够检测是否丢包 {第一个包，认为丢包，超时认为丢包；}<=
MultiFrameRTPSource::doGetNextFrame1() {计算并跳过特别的头； 组合一帧数据； 如果一帧结束或没有缓冲数据了，则返回；传递给上层的数据一定是完整的帧。}
综上，如果发生超时也会导致一帧数据的丢失

从网络接收数据的过程
MultiFramedRTPSource::doGetNextFrame() {fAreDoingNetworkReads = True;}=>
MultiFramedRTPSrouce::networkReadHandler1() {接着用上一次的包，准备接收数据，如果没有则从缓冲队列中分配一个;
如果是接着用上一次的包，说明此次读过程还不完整packetReadWasIncomplete＝true； }=>
BufferedPacket::fillInData() {如果读的是完整的，则复位；}=>
BufferedPacket::reset()=>{fIsFirstPacket = False;  fUseCount = 0; fHead = fTail = 0;}<=
综上，如果MultiFrameRTPSource接着用上一次的包，则不会复位，如果不是用上一次的包，是新包，则会复位。
RTPInterface::handleRead() {如果是UDP包，那么包肯定是完整的，packetReadWasIncomplete = False;}<=
ultiFramedRTPSrouce::networkReadHandler1() {当为UDP传输时，fPacketReadInProgress = NULL; 利用RTP包更新统计数据； 把RTP包存入缓冲fReorderingBuffer；}=>
ReorderingPacketBuffer::storePacket() {如果是新的源，则这个包是这个缓冲的第一个包，fNextExpectedSeqNo = rtpSeqNo; 排序存入；}=>
MultiFrameRTPSource::doGetNextFrame1()


ReorderingPacketBuffer的工作方法：
一个去乱序的缓冲队列，以时间为门限
第一个包认为是之前发生过丢包，

综上，live555确保了向上层传递的帧是完整帧，但没有把帧间是否发生丢失的信息进行上传。





















 */





